package pdf;

import com.spire.pdf.FileFormat;
import com.spire.pdf.PdfDocument;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.text.PDFTextStripper;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import util.PythonUtil;

import java.io.*;

/**
 * 效果差，没什么用
 * pdf转word
 * https://blog.csdn.net/sunghosts/article/details/121157479
 * 方式1：直接使用工具将pdf转成word
 * 1.1.apache PDFBox工具包、Spire.PDF、itextpdf
 * 1.2.COM技术，利用java调用windows平台的COM组件完成转换，Adobe的Acrobat软件在pdf转word中功能良好，Jacob可以实现java代码和COM组件之间的互操作
 * 方式2：先用工具将pdf中的内容提取出来，再使用其他工具将内容创建到新的word中
 */
public class PDF2WordUtil {

    public static void main(String[] args) {
        // 文件路径
        String filePath = "G:\\黑马资料java视频教程2021\\资料-2022MySQL数据库\\文档\\MySQL-运维篇.pdf";

        // pdf2wordBySpire(filePath);
        // pdf2wordByPDFBox(filePath);
        pdf2wordByPython(filePath);
    }

    /**
     * 使用spire.pdf
     * 效果还行，图片也能转，第一页会有水印，但是word嘛，自己手动删除即可
     * https://www.cnblogs.com/lxz123/p/15180719.html
     */
    public static void pdf2wordBySpire(String filePath) {
        // Create a PdfDocument instance
        PdfDocument pdf = new PdfDocument();
        // Load a PDF file
        pdf.loadFromFile(filePath);
        // Save to .docx file
        String outputFile = filePath.substring(0, filePath.lastIndexOf("."));
        pdf.saveToFile(outputFile + "_1.docx", FileFormat.DOCX);
        pdf.close();
        // 转换需要一些时间，耐心等待
        System.out.println("spire.pdf：pdf转换word成功！");

        // 去除第一行水印
        // 方法有问题，笨笨的就不浪费时间研究了
        // removeShuiYinBySpire(outputFile + "_1.docx", outputFile + "_1_1.docx");
    }

    /**
     * Apache PDFBox将pdf转换为word
     * 只能转换文字，而且没有格式，没有图片
     * https://blog.csdn.net/Zhangsama1/article/details/123547720
     * https://www.cnblogs.com/angin-iit/p/10551829.html
     */
    public static void pdf2wordByPDFBox(String filePath) {
        try {
            // 将pdf加载到对象中去
            PDDocument doc = PDDocument.load(new File(filePath));
            // 得到pdf的页数
            int pagenumber = doc.getNumberOfPages();
            // 设置转换后的名字
            String fileName = filePath.substring(0, filePath.lastIndexOf(".")) + "_2.doc";
            File file = new File(fileName);
            if (!file.exists()) {
                file.createNewFile();
            }
            FileOutputStream fos = new FileOutputStream(fileName);
            // 设置输出字符集为UTF-8 因此该word应该使用UTF-8格式打开 如果你出现乱码那么你可以自己修改一下这里的格式
            Writer writer = new OutputStreamWriter(fos, "UTF-8");
            PDFTextStripper stripper = new PDFTextStripper();
            // 排序
            stripper.setSortByPosition(true);
            // 设置转换的开始页
            stripper.setStartPage(1);
            // 设置转换的结束页
            stripper.setEndPage(pagenumber);
            stripper.writeText(doc, writer);
            writer.close();
            doc.close();
            System.out.println("PDFBox：pdf转换word成功！");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * java调用python脚本：pdf2docx
     * 个人博客：https://blog.csdn.net/weixin_44174211/article/details/124371826
     * https://blog.csdn.net/doublezsx/article/details/79724662
     * https://blog.csdn.net/dl962454/article/details/102915283
     */
    public static void pdf2wordByPython(String filePath) {
        // 解释器
        String exe = "python";
        // python脚本路径，需要使用绝对路径
        // String command = "PdfToDocx.py";
        String command = "F:\\学习项目\\java-learn-demo\\java-tools\\src\\main\\java\\pdf\\PdfToDocx.py";
        String sourceFilePath = filePath;
        String targetFilePath = filePath.substring(0, filePath.lastIndexOf(".")) + "_3.docx";
        // 组合成一个字符串数组
        String[] cmdArr = new String[]{exe, command, sourceFilePath, targetFilePath};
        
        PythonUtil.executePythonScript(cmdArr);

    }

    /**
     * 去除Spire生成word的第一行水印
     * 是操作word的，不要找错场子到pdf拆分了
     * 不知道是删除第一个元素的原因，还是读取的原因，页数从83-->18
     * https://java-jie.blog.csdn.net/article/details/123347458
     *
     * @param oldFilePath 原路径
     * @param newFilePath 新路径
     */
    public static void removeShuiYinBySpire(String oldFilePath, String newFilePath) {
        try (InputStream is = new FileInputStream(oldFilePath)) {
            // 将文档输入input流
            // InputStream is = new FileInputStream(oldFilePath);
            // org.apache.poi.openxml4j.exceptions.NotOfficeXmlFileException: No valid entries or contents found
            // 代表一个docx文档
            // 显而易见的,读xml 比开XWPFDocument 不知道快多少倍,前提文档是 docx
            // 卡了很久
            XWPFDocument document = new XWPFDocument(is);
            // Spire的产品 生成的文件会自带同步警告信息，这里来删除Spire产品的的警告信息
            document.removeBodyElement(0);
            // 将文件流put到新的文件中
            // OutputStream os = new FileOutputStream(newFilePath);
            try (OutputStream os = new FileOutputStream(newFilePath)) {
                document.write(os);
                System.out.println("水印去除完成，文档生成成功");
            } catch (Exception e) {
                e.printStackTrace();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

}
